﻿using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Reflection;

namespace ApiServer.SwaggerExt
{
    /// <summary>
    /// Swagger扩展
    /// </summary>
    public static class CustomSwaggerExt
    {
        /// <summary>
        /// 配置Swagger
        /// </summary>
        /// <param name="builder"></param>
        public static void AddSwaggerExt(this WebApplicationBuilder builder)
        {
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen(option =>
            {

                typeof(ApiVersions).GetEnumNames().ToList().ForEach(version =>
                {
                    option.SwaggerDoc(version, new OpenApiInfo()
                    {
                        Title = $"JHY后台管理实战Api服务",
                        Version = version,
                        Description = $"通用版本的CoreApi版本{version}"
                    });


                    option.OperationFilter<SwaggerFileUploadFilter>();
                });

                // xml文档绝对路径 
                var file = Path.Combine(AppContext.BaseDirectory, "ApiServer.xml");
                // true : 显示控制器层注释
                option.IncludeXmlComments(file, true);
                // 对action的名称进行排序，如果有多个，就可以看见效果了。
                option.OrderActionsBy(o => o.RelativePath);

                //添加安全定义
                option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "请输入token,格式为 Bearer xxxxxxxx（注意中间必须有空格）",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey,
                    BearerFormat = "JWT",
                    Scheme = "Bearer"
                });
                //添加安全要求
                option.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                  {
                        new OpenApiSecurityScheme
                        {
                            Reference =new OpenApiReference()
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id ="Bearer"
                            }
                        },
                        new string[]{ }
                    }
                });
            });
        }

        /// <summary>
        /// 中间件生效
        /// </summary>
        /// <param name="app"></param>
        public static void UseSwaggerExt(this WebApplication app)
        {
            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                foreach (string version in typeof(ApiVersions).GetEnumNames())
                {
                    c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"第【{version}】版本");
                }
            });
        }
    }

    /// <summary>
    /// 扩展swg   支持选择文件上传
    /// </summary>
    public class SwaggerFileUploadFilter : IOperationFilter
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="operation"></param>
        /// <param name="context"></param>
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            const string FileUploadContentType = "multipart/form-data";
            if (operation.RequestBody == null ||
                !operation.RequestBody.Content.Any(x =>
                x.Key.Equals(FileUploadContentType, StringComparison.InvariantCultureIgnoreCase)))
            {
                return;
            }

            if (context.ApiDescription.ActionDescriptor.Parameters.Any(c => c.ParameterType == typeof(IFormFile)))
            {
                operation.RequestBody = new OpenApiRequestBody
                {
                    Description = "文件上传 可以自己定义各种文字",
                    Content = new Dictionary<string, OpenApiMediaType>
                    {
                         {
                            FileUploadContentType, new OpenApiMediaType
                            {
                                Schema = new OpenApiSchema
                                {
                                    Type = "object",
                                    Required = new HashSet<string>{ "file" },
                                    Properties = new Dictionary<string, OpenApiSchema>
                                    {
                                        {
                                            "file", new OpenApiSchema()
                                            {
                                                Type = "string",
                                                Format = "binary"
                                            }
                                        }
                                    }
                                }
                            }
                         }
                    }
                };
            }
        }
    }



}


